package repository

import (
	v1 "SmartLibrary/api/v1"
	"SmartLibrary/internal/model"
	"context"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"strings"
	"time"
)

type AdminRepository interface {
	GetByUsername(ctx context.Context, username string) (*model.Admins, error)
	GetBookLists(ctx context.Context, req *v1.AdminGetListsRequest) (*[]model.AdminBooks, error)
	GetBooksCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error)
	GetBookTypes(ctx context.Context) (*[]v1.AdminBookTypeResponse, error)
	AddBooks(ctx context.Context, req *v1.AdminBook) error
	DeleteBooks(ctx context.Context, id string) error
	GetBookInformation(ctx context.Context, id string) (model.AdminBooks, error)
	PutBookInformation(ctx context.Context, v *v1.AdminPutBook) error
	GetBookTypeList(ctx context.Context, req *v1.AdminGetListsRequest) ([]model.AdminBookType, error)
	GetAllBookTypeList(ctx context.Context) ([]model.AdminBookType, error)
	GetBookTypeInformation(ctx context.Context, id string) (model.AdminBookType, error)
	AddBookTypes(ctx context.Context, req *v1.AdminBookTypeRequest) error
	DeleteBookType(ctx context.Context, id string) error
	PutBookTypeInformation(ctx context.Context, req *v1.AdminBookTypeRequest) error
	GetLibraryCardsList(ctx context.Context, v *v1.AdminGetListsRequest) ([]model.AdminUsers, error)
	GetLibraryCardsCount(ctx context.Context, v *v1.AdminGetListsRequest) (int64, error)
	AddLibraryCard(ctx context.Context, v *v1.AdminLibraryCardRequest) error
	GetLibraryCard(ctx context.Context, id string) (model.AdminUsers, error)
	PutLibraryCard(ctx context.Context, v *v1.AdminLibraryPutCardRequest) error
	DeleteLibraryCard(ctx context.Context, id string) error
	GetBorrowsList(ctx context.Context, v *v1.AdminGetListsRequest) ([]model.AdminBooksBorrow, error)
	GetBorrowsCount(ctx context.Context, v *v1.AdminGetListsRequest) (int64, error)
	GetBorrowRulesList(ctx context.Context, v *v1.AdminGetListsRequest) ([]model.AdminBookRule, error)
	GetBorrowRulesCount(ctx context.Context, v *v1.AdminGetListsRequest) (int64, error)
	AddBorrowRules(ctx context.Context, v *v1.AdminBookBorrowRulesRequest) error
	GetBorrowRules(ctx context.Context, id *string) (model.AdminBookRule, error)
	PutBorrowRules(ctx context.Context, v *v1.AdminPutBookBorrowRulesRequest) error
	DeleteBorrowRules(ctx context.Context, id string) error
	GetBookAdminList(ctx context.Context, v *v1.AdminGetListsRequest) ([]model.AdminBookAdmins, error)
	GetBookAdminsCount(ctx context.Context, v *v1.AdminGetListsRequest) (int64, error)
	AddBookAdmin(ctx context.Context, v *v1.AdminBookAdminRequest) error
	GetBookAdmin(ctx context.Context, id *string) (model.AdminBookAdmins, error)
	PutBookAdmin(ctx context.Context, v *v1.AdminPutBookAdminRequest) error
	DeleteBookAdmin(ctx context.Context, id string) error
	GetBorrowsData(ctx context.Context) ([]model.AdminBooksBorrow, error)
	GetBorrowTypeData(ctx context.Context, borrowTypeData *[]v1.AdminBorrowTypeData, borrows *[]model.AdminBooksBorrow) error
	AddAdmin(ctx context.Context, v *v1.AdminRegisterRequest) error
	DeleteAllBooks(ctx context.Context, v *v1.AdminDeleteBooksRequest) error
	GetBookTypeCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error)
	GetBorrowAllRulesList(ctx context.Context) ([]int64, error)
	PutLibraryCardRuleNumber(ctx context.Context, v *v1.AdminLibraryPutCardRuleNumberRequest) error
}

func NewAdminRepository(
	repository *Repository,
) AdminRepository {
	return &adminRepository{
		Repository: repository,
	}
}

type adminRepository struct {
	*Repository
}

func (r *adminRepository) AddAdmin(ctx context.Context, v *v1.AdminRegisterRequest) error {
	return r.DB(ctx).Create(&model.Admins{
		Username:   v.UserName,
		Password:   v.Password,
		Status:     0,
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	}).Error
}

func (r *adminRepository) GetByUsername(ctx context.Context, username string) (*model.Admins, error) {
	var admin model.Admins
	if err := r.DB(ctx).Where("username = ?", username).First(&admin).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, v1.ErrAdminUsernameOrPasswordWrong
		}
		return nil, err
	}
	return &admin, nil
}
func (r *adminRepository) GetBookTypes(ctx context.Context) (*[]v1.AdminBookTypeResponse, error) {
	var bookTypes []v1.AdminBookTypeResponse
	err := r.DB(ctx).Model(&model.AdminBookType{}).Find(&bookTypes).Error
	return &bookTypes, err
}
func (r *adminRepository) GetBookTypeCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error) {
	var counts int64
	if req.Query == "" || req.Condition == "" {
		if err := r.DB(ctx).Model(&model.AdminBookType{}).Count(&counts).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return 0, v1.ErrAdminBookTypeNotFound
			}
			return 0, err
		}
	} else {
		if err := r.DB(ctx).Model(&model.AdminBookType{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Count(&counts).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return 0, v1.ErrAdminBookTypeNotFound
			}
			return 0, err
		}
	}

	return counts, nil
}

// GetBooksCount 根据request中的查询字段和查询条件获取图书数量
func (r *adminRepository) GetBooksCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error) {
	var books int64
	if req.Query == "" || req.Condition == "" {
		// 如果 req.Query 为空，可以选择跳过 LIKE 子句或使用一个始终为真的条件
		if err := r.DB(ctx).Model(&model.AdminBooks{}).Count(&books).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return 0, v1.ErrAdminBookNotFound
			}
			return 0, err
		}
	} else {
		if err := r.DB(ctx).Model(&model.AdminBooks{}).Where(req.Query+" LIKE ?", "%"+req.Condition+"%").Count(&books).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return 0, v1.ErrAdminBookNotFound
			}
			return 0, err
		}
	}
	return books, nil
}

// GetBookTypeList 获取图书类型列表
func (r *adminRepository) GetBookTypeList(ctx context.Context, req *v1.AdminGetListsRequest) ([]model.AdminBookType, error) {
	var bookTypes []model.AdminBookType
	if req.Query == "" || req.Condition == "" {
		if err := r.DB(ctx).Model(&model.AdminBookType{}).Offset(req.Offset).Limit(req.Limit).Find(&bookTypes).Error; err != nil {
			return nil, err
		}
	} else {
		if err := r.DB(ctx).Model(&model.AdminBookType{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Offset(req.Offset).Limit(req.Limit).Find(&bookTypes).Error; err != nil {
			return nil, err
		}
	}
	return bookTypes, nil
}
func (r *adminRepository) GetAllBookTypeList(ctx context.Context) ([]model.AdminBookType, error) {
	var bookTypes []model.AdminBookType
	if err := r.DB(ctx).Model(&model.AdminBookType{}).Find(&bookTypes).Error; err != nil {
		return nil, err
	}
	return bookTypes, nil
}
func (r *adminRepository) GetBookTypeInformation(ctx context.Context, id string) (model.AdminBookType, error) {
	var bookType model.AdminBookType
	if err := r.DB(ctx).Where("type_id = ?", id).First(&bookType).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return model.AdminBookType{}, v1.ErrAdminBookTypeNotFound
		}
		return model.AdminBookType{}, err
	}
	return bookType, nil
}
func (r *adminRepository) AddBooks(ctx context.Context, req *v1.AdminBook) error {
	return r.DB(ctx).Create(&model.AdminBooks{
		BookNumber:      int64(req.BookNumber),
		BookName:        req.BookName,
		BookAuthor:      req.BookAuthor,
		BookLibrary:     req.BookLibrary,
		BookType:        req.BookType,
		BookLocation:    req.BookLocation,
		BookStatus:      req.BookStatus,
		BookDescription: req.BookDescription,
		CreateTime:      time.Now(),
		UpdateTime:      time.Now(),
	}).Error
}
func (r *adminRepository) DeleteBooks(ctx context.Context, id string) error {
	// 删除记录中delete操作在没有找到记录的情况下并不会返回错误
	result := r.DB(ctx).Where("book_id = ?", id).Delete(&model.AdminBooks{})
	if result.Error != nil {
		return result.Error
	} else if result.RowsAffected == 0 {
		// 没有记录被删除
		return v1.ErrAdminBookNotFound
	}
	return nil
}

// GetBookInformation 获取图书信息
func (r *adminRepository) GetBookInformation(ctx context.Context, id string) (model.AdminBooks, error) {
	var book model.AdminBooks
	if err := r.DB(ctx).Where("book_id = ?", id).First(&book).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return model.AdminBooks{}, v1.ErrAdminBookNotFound
		}
		return model.AdminBooks{}, err
	}
	return book, nil
}
func (r *adminRepository) PutBookInformation(ctx context.Context, v *v1.AdminPutBook) error {

	result := r.DB(ctx).Model(&model.AdminBooks{}).Where("book_number = ?", v.BookNumber).Updates(model.AdminBooks{
		BookName:        v.BookName,
		BookAuthor:      v.BookAuthor,
		BookLibrary:     v.BookLibrary,
		BookType:        v.BookType,
		BookLocation:    v.BookLocation,
		BookStatus:      v.BookStatus,
		BookDescription: v.BookDescription,
		UpdateTime:      time.Now(),
	})
	if result.RowsAffected == 0 {
		return v1.ErrAdminBookNotFound
	}
	return result.Error
}

// GetBookLists 获取图书列表
func (r *adminRepository) GetBookLists(ctx context.Context, req *v1.AdminGetListsRequest) (*[]model.AdminBooks, error) {
	var books []model.AdminBooks
	if req.Query == "" || req.Condition == "" {
		if err := r.DB(ctx).Offset(req.Offset).Limit(req.Limit).Find(&books).Error; err != nil {
			r.logger.Debug(fmt.Sprintf("GetBookLists error: %v", err))
			return nil, err
		}
	} else {
		if err := r.DB(ctx).Where(req.Query+" LIKE ? ", "%"+req.Condition+"%").Offset(req.Offset).Limit(req.Limit).Find(&books).Error; err != nil {
			r.logger.Debug(fmt.Sprintf("GetBookLists error: %v", err))
			return nil, err
		}
	}
	return &books, nil
}
func (r *adminRepository) AddBookTypes(ctx context.Context, req *v1.AdminBookTypeRequest) error {
	result := r.DB(ctx).Create(&model.AdminBookType{
		TypeName:    req.TypeName,
		TypeContent: req.TypeContent,
		CreateTime:  time.Now(),
		UpdateTime:  time.Now(),
	})
	if result.Error != nil {
		// 判断是否为用户名重复错误
		if strings.Contains(result.Error.Error(), "Duplicate entry") {
			// 返回一个自定义的错误
			return v1.ErrAdminBookTypeDuplicate
		}
		return result.Error
	}
	return nil
}
func (r *adminRepository) DeleteBookType(ctx context.Context, id string) error {
	result := r.DB(ctx).Where("type_id = ?", id).Delete(&model.AdminBookType{})
	if result.RowsAffected == 0 {
		// 没有记录被删除
		return v1.ErrAdminBookTypeNotFound
	}
	return result.Error
}

// PutBookTypeInformation 更新图书类型信息
func (r *adminRepository) PutBookTypeInformation(ctx context.Context, req *v1.AdminBookTypeRequest) error {
	result := r.DB(ctx).Model(&model.AdminBookType{}).Where("type_id = ?", req.TypeID).Updates(model.AdminBookType{
		TypeName:    req.TypeName,
		TypeContent: req.TypeContent,
		UpdateTime:  time.Now(),
	})
	if result.RowsAffected == 0 {
		return v1.ErrAdminBookTypeNotFound
	}
	return result.Error
}

// GetLibraryCardsList 获取借阅卡列表
func (r *adminRepository) GetLibraryCardsList(ctx context.Context, req *v1.AdminGetListsRequest) ([]model.AdminUsers, error) {
	var users []model.AdminUsers
	if req.Query == "" || req.Condition == "" {
		if err := r.DB(ctx).Model(&model.AdminUsers{}).Offset(req.Offset).Limit(req.Limit).Find(&users).Error; err != nil {
			return nil, err
		}
	} else {
		if err := r.DB(ctx).Model(&model.AdminUsers{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Offset(req.Offset).Limit(req.Limit).Find(&users).Error; err != nil {
			return nil, err
		}
	}
	return users, nil
}

// GetLibraryCardsCount 获取借阅卡数量
func (r *adminRepository) GetLibraryCardsCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error) {
	var users int64
	if req.Query == "" || req.Condition == "" {
		if err := r.DB(ctx).Model(&model.AdminUsers{}).Count(&users).Error; err != nil {
			return 0, err
		}
	} else {
		if err := r.DB(ctx).Model(&model.AdminUsers{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Count(&users).Error; err != nil {
			return 0, err
		}
	}
	return users, nil
}

// AddLibraryCard 添加图书借阅卡
func (r *adminRepository) AddLibraryCard(ctx context.Context, v *v1.AdminLibraryCardRequest) error {
	result := r.DB(ctx).Create(&model.AdminUsers{
		Username:   v.UserName,
		Password:   v.Password,
		CardNumber: v.CardNumber,
		RuleNumber: v.RuleNumber,
		Status:     *v.UserStatus,
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	})
	if result.Error != nil {
		// 判断是否为用户名重复错误
		if strings.Contains(result.Error.Error(), "Duplicate entry") {
			// 返回一个自定义的错误
			return v1.ErrAdminLibraryCardUsernameAlreadyExists
		}
		return result.Error
	}
	return nil
}

// GetLibraryCard 获取图书借阅卡
func (r *adminRepository) GetLibraryCard(ctx context.Context, id string) (model.AdminUsers, error) {
	var user model.AdminUsers
	if err := r.DB(ctx).Where("user_id = ?", id).First(&user).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return model.AdminUsers{}, v1.ErrAdminLibraryCardNotFound
		}
		return model.AdminUsers{}, err
	}
	return user, nil
}
func (r *adminRepository) PutLibraryCard(ctx context.Context, v *v1.AdminLibraryPutCardRequest) error {
	result := r.DB(ctx).Model(&model.AdminUsers{}).Where("user_id = ?", v.UserId).Updates(model.AdminUsers{
		Username:   v.UserName,
		Password:   v.Password,
		RuleNumber: v.RuleNumber,
		Status:     *v.UserStatus,
		UpdateTime: time.Now(),
	})
	if result.RowsAffected == 0 {
		return v1.ErrAdminLibraryCardNotFound
	}
	if result.Error != nil {
		// 判断是否为用户名重复错误
		if strings.Contains(result.Error.Error(), "duplicate key value violates unique constraint") {
			// 返回一个自定义的错误
			return v1.ErrAdminUsernameAlreadyUse
		}
		// 其他错误直接返回
		return result.Error
	}
	return nil
}
func (r *adminRepository) DeleteLibraryCard(ctx context.Context, id string) error {
	result := r.DB(ctx).Where("user_id = ?", id).Delete(&model.AdminUsers{})
	if result.RowsAffected == 0 {
		// 没有记录被删除
		return v1.ErrAdminLibraryCardNotFound
	}
	return result.Error
}
func (r *adminRepository) GetBorrowsList(ctx context.Context, req *v1.AdminGetListsRequest) ([]model.AdminBooksBorrow, error) {
	var borrows []model.AdminBooksBorrow
	var err error
	if req.Query == "" || req.Condition == "" {
		err = r.DB(ctx).Model(&model.AdminBooksBorrow{}).Offset(req.Offset).Limit(req.Limit).Find(&borrows).Error
	} else {
		err = r.DB(ctx).Model(&model.AdminBooksBorrow{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Offset(req.Offset).Limit(req.Limit).Find(&borrows).Error
	}

	return borrows, err
}
func (r *adminRepository) GetBorrowsCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error) {
	var borrows int64
	var err error
	if req.Query == "" || req.Condition == "" {
		err = r.DB(ctx).Model(&model.AdminBooksBorrow{}).Count(&borrows).Error
	} else {
		err = r.DB(ctx).Model(&model.AdminBooksBorrow{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Count(&borrows).Error
	}
	return borrows, err
}
func (r *adminRepository) GetBorrowAllRulesList(ctx context.Context) ([]int64, error) {
	var rules []int64
	err := r.DB(ctx).Model(&model.AdminBookRule{}).Select("book_rule_id").Find(&rules).Error
	return rules, err
}
func (r *adminRepository) GetBorrowRulesList(ctx context.Context, req *v1.AdminGetListsRequest) ([]model.AdminBookRule, error) {
	var rules []model.AdminBookRule
	var err error
	if req.Query == "" || req.Condition == "" {
		err = r.DB(ctx).Model(&model.AdminBookRule{}).Offset(req.Offset).Limit(req.Limit).Find(&rules).Error
	} else {
		err = r.DB(ctx).Model(&model.AdminBookRule{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Offset(req.Offset).Limit(req.Limit).Find(&rules).Error
	}
	return rules, err
}
func (r *adminRepository) GetBorrowRulesCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error) {
	var rules int64
	if req.Query == "" || req.Condition == "" {
		if err := r.DB(ctx).Model(&model.AdminBookRule{}).Count(&rules).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return 0, v1.ErrAdminBookBorrowRulesNotFound
			}
			return 0, err
		}
	} else {
		if err := r.DB(ctx).Model(&model.AdminBookRule{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Count(&rules).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return 0, v1.ErrAdminBookBorrowRulesNotFound
			}
			return 0, err
		}
	}
	return rules, nil
}
func (r *adminRepository) AddBorrowRules(ctx context.Context, v *v1.AdminBookBorrowRulesRequest) error {
	result := r.DB(ctx).Create(&model.AdminBookRule{
		BookRuleID:       v.BookRuleId,
		BookDays:         v.BookLimitDays,
		BookLimitLibrary: v.BookLimitLibrary,
		BookLimitNumber:  v.BookLimitNumber,
		BookOverdueFee:   v.BookOverdueFee,
		CreateTime:       time.Now(),
		UpdateTime:       time.Now(),
	})
	if result.Error != nil {
		// 判断是否为用户名重复错误
		if strings.Contains(result.Error.Error(), "Duplicate entry") {
			// 返回一个自定义的错误
			return v1.ErrAdminBookRuleIdAlreadyExists
		}
		return result.Error
	}
	return nil
}
func (r *adminRepository) GetBorrowRules(ctx context.Context, id *string) (model.AdminBookRule, error) {
	var rule model.AdminBookRule
	if err := r.DB(ctx).Where("rule_id = ?", id).First(&rule).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return model.AdminBookRule{}, v1.ErrAdminBookBorrowRulesNotFound
		}
		return model.AdminBookRule{}, err
	}
	return rule, nil
}
func (r *adminRepository) PutBorrowRules(ctx context.Context, v *v1.AdminPutBookBorrowRulesRequest) error {
	result := r.DB(ctx).Model(&model.AdminBookRule{}).Where("rule_id = ?", v.RuleId).Updates(model.AdminBookRule{
		BookRuleID:       v.BookRuleId,
		BookDays:         v.BookLimitDays,
		BookLimitLibrary: v.BookLimitLibrary,
		BookLimitNumber:  v.BookLimitNumber,
		BookOverdueFee:   v.BookOverdueFee,
		UpdateTime:       time.Now(),
	})

	if result.Error != nil {
		// 判断是否为用户名重复错误
		if strings.Contains(result.Error.Error(), "Duplicate entry") {
			return v1.ErrAdminBookRuleIdAlreadyExists
		}
		return result.Error
	}
	if result.RowsAffected == 0 {
		return v1.ErrAdminBookBorrowRulesNotFound
	}
	return nil
}
func (r *adminRepository) DeleteBorrowRules(ctx context.Context, id string) error {
	result := r.DB(ctx).Where("rule_id = ?", id).Delete(&model.AdminBookRule{})
	if result.RowsAffected == 0 {
		// 没有记录被删除
		return v1.ErrAdminBookBorrowRulesNotFound
	}
	return result.Error
}
func (r *adminRepository) GetBookAdminList(ctx context.Context, req *v1.AdminGetListsRequest) ([]model.AdminBookAdmins, error) {
	var admins []model.AdminBookAdmins
	var err error
	if req.Query == "" || req.Condition == "" {
		err = r.DB(ctx).Model(&model.AdminBookAdmins{}).Offset(req.Offset).Limit(req.Limit).Find(&admins).Error
	} else {
		err = r.DB(ctx).Model(&model.AdminBookAdmins{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Offset(req.Offset).Limit(req.Limit).Find(&admins).Error
	}
	return admins, err
}
func (r *adminRepository) GetBookAdminsCount(ctx context.Context, req *v1.AdminGetListsRequest) (int64, error) {
	var admins int64
	var err error
	if req.Query == "" || req.Condition == "" {
		err = r.DB(ctx).Model(&model.AdminBookAdmins{}).Count(&admins).Error
	} else {
		err = r.DB(ctx).Model(&model.AdminBookAdmins{}).Where(req.Query + " LIKE ?" + "%" + req.Condition + "%").Count(&admins).Error
	}
	return admins, err
}
func (r *adminRepository) AddBookAdmin(ctx context.Context, v *v1.AdminBookAdminRequest) error {
	result := r.DB(ctx).Create(&model.AdminBookAdmins{
		BookAdminName: v.BookAdminName,
		Email:         v.Email,
		Password:      v.Password,
		Username:      v.UserName,
		CreateTime:    time.Now(),
		UpdateTime:    time.Now(),
	})
	if result.Error != nil {
		// 判断是否为用户名重复错误
		if strings.Contains(result.Error.Error(), "Duplicate entry") {
			return v1.ErrAdminBookAdminsDuplicate
		}
		return result.Error
	}
	return nil
}

// GetBookAdmin 获取图书管理员
func (r *adminRepository) GetBookAdmin(ctx context.Context, id *string) (model.AdminBookAdmins, error) {
	var admin model.AdminBookAdmins
	if err := r.DB(ctx).Where("book_admin_id = ?", id).First(&admin).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return model.AdminBookAdmins{}, v1.ErrAdminBookAdminsNotFound
		}
		return model.AdminBookAdmins{}, err
	}
	return admin, nil
}
func (r *adminRepository) PutBookAdmin(ctx context.Context, v *v1.AdminPutBookAdminRequest) error {
	result := r.DB(ctx).Model(&model.AdminBookAdmins{}).Where("book_admin_id = ?", v.BookAdminId).Updates(model.AdminBookAdmins{
		BookAdminName: v.BookAdminName,
		Email:         v.Email,
		Password:      v.Password,
		Username:      v.UserName,
	})
	if result.RowsAffected == 0 {
		return v1.ErrAdminBookAdminsNotFound
	}
	if result.Error != nil {
		// 判断是否为用户名重复错误
		if strings.Contains(result.Error.Error(), "duplicate key value violates unique constraint") {
			// 返回一个自定义的错误
			return v1.ErrAdminBookAdminsUsernameAlreadyExists
		}
		// 其他错误直接返回
		return result.Error
	}
	return nil
}

// DeleteBookAdmin 删除图书管理员
func (r *adminRepository) DeleteBookAdmin(ctx context.Context, id string) error {
	result := r.DB(ctx).Where("book_admin_id = ?", id).Delete(&model.AdminBookAdmins{})
	if result.RowsAffected == 0 {
		// 没有记录被删除
		return v1.ErrAdminBookAdminsNotFound
	}
	return result.Error
}

// GetBorrowsData 获取借阅数据
func (r *adminRepository) GetBorrowsData(ctx context.Context) ([]model.AdminBooksBorrow, error) {
	var borrowsRecord []model.AdminBooksBorrow
	currentDate := time.Now()
	//返回当前日期及前28天的记录返回
	startDate := currentDate.AddDate(0, 0, -28)
	err := r.DB(ctx).Model(&model.AdminBooksBorrow{}).Where("borrow_date >= ?", startDate).Find(&borrowsRecord).Error
	return borrowsRecord, err
}
func (r *adminRepository) GetBorrowTypeData(ctx context.Context, borrowTypeData *[]v1.AdminBorrowTypeData, borrows *[]model.AdminBooksBorrow) error {
	//1.用borrows切片中的card_number去books表中查询其书本类型，然后将书本类型types结构体中对应的类型的book_number加1
	// 开启事务
	tx := r.DB(ctx).Begin()

	for _, borrow := range *borrows {
		var bookType model.AdminBooks
		// 根据 borrows.card_number 和 Book.card_number 查询 BookType
		if err := tx.Model(&model.AdminBooks{}).Where("book_number  = ?", borrow.CardNumber).First(&bookType).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				continue
			}
			tx.Rollback()
			return err
		}
		// 将 book_number 加 1
		for i, borrowTypeResult := range *borrowTypeData {
			if borrowTypeResult.BorrowType == bookType.BookType {
				(*borrowTypeData)[i].BorrowNumbers++
			}
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		return err
	}
	return nil
}

// DeleteAllBooks 删除所有图书
func (r *adminRepository) DeleteAllBooks(ctx context.Context, v *v1.AdminDeleteBooksRequest) error {
	for _, id := range v.BookIds {
		err := r.DB(ctx).Where("book_id = ?", id).Delete(&model.AdminBooks{}).Error
		if err != nil {
			return err
		}
	}
	return nil
}
func (r *adminRepository) PutLibraryCardRuleNumber(ctx context.Context, v *v1.AdminLibraryPutCardRuleNumberRequest) error {
	result := r.DB(ctx).Model(&model.AdminUsers{}).Where("user_id = ?", v.UserId).Updates(model.AdminUsers{
		RuleNumber: v.RuleNumber,
	})
	if result.RowsAffected == 0 {
		return v1.ErrAdminLibraryCardNotFound
	}
	if result.Error != nil {
		return result.Error
	}
	return nil
}
